package ControllerLayer;
import ModelLayer.*;

import java.util.ArrayList;
/**
 * ItemCtr functions as a controller for the ItemCon and Item (including Product and Composition)
 * classes in the ModelLayer.
 * Any changes to instances of those classes will go through this controller.
 * 
 * @author  Mie P., Danny M.P., Jakob K., Anna K., Anders A.P.  
 * @version 1.0
 */
public class ItemCtr {

    private ItemCon     itemCon;
    private SupplierCon supplierCon;
    private Composition c;

    /**
     * Constructor for objects of class ItemCtr
     */
    public ItemCtr() {

        supplierCon = SupplierCon.getInstance();
        itemCon = ItemCon.getInstance();
        
    }
    
    /**
     * Method for creating an instance of Product, and adding it to the ItemContainer.
     * 
     * @param name              name of the product.
     * @param description       a description of the product.
     * @param supplier          the supplier of the product. The supplier must be created in the system.
     * @param quantityInBulk    the number of products in a package, eg. 10 in one package.
     * @param purchasePrice     the price paid to the supplier for the product.
     * @param size              the size of the product measured in cubic cm.
     * @param weight            the weight of the product.
     * @throws Exception 
     */
    public void createProduct(String name, String description, int supplierID, int quantityInBulk,
                              double purchasePrice, double size, double weight) throws Exception {

        Supplier supplier = supplierCon.getSupplier(supplierID);
        Product p = new Product(name, description, supplier, quantityInBulk, purchasePrice, size, weight);
        itemCon.addItem(p);

    }

    /**
     * Method for creating an instance of Composition, and adding it to the ItemContainer.
     * 
     * @param name          name of the composition.
     * @param description   a description of the composition.
     * @throws Exception 
     */
    public void createComposition(String name, String description) throws Exception {

        c = new Composition(name, description);
        itemCon.addItem(c);

    }

    /**
     * Method for adding a product to a composition.
     * 
     * @param c             the Compositon object.
     * @param p             the Product object to be added.
     * @param quantity      the quantity of the product.
     */
    public void addProductToComp(Product p, int quantity) {

        c.addProduct(p, quantity);

    }

    /**
     * Method that finds an Item object in the ItemCon and returns it.
     * The item object can be an instance of either Product or Composition.
     * 
     * @param  itemID       the ID used to find the item.
     * @return i            an Item object.
     * @throws Exception    if the item is not found.
     */
    public Item retrieveItem(int itemID) throws Exception {

        Item i = itemCon.getItem(itemID);
        if (i instanceof Composition) {
            c = (Composition)i;
        }
        return i;

    }

    /**
     * Method to set the sales price of a product, both ordinary price and bulk price.
     * 
     * @param p                 The Product object.
     * @param salesPrice        The price for a single piece of the product.
     * @param salesPriceBulk    The price for a package of the product.
     *                          The package size is defined in the product object.
     */
    public void setProductPrice(Product p, double salesPrice, double salesPriceBulk) {

        p.setSalesPrice(salesPrice);
        if (p.getQuantityInBulk() == 1) {
            p.setSalesPriceBulk(salesPrice);
        }
        else {
            p.setSalesPriceBulk(salesPriceBulk);
        }

    }

    /**
     * Method to set the sales price of a composition.
     * 
     * @param c                 the Compositon object.
     * @param salesPrice        the price of the composition.
     */
    public void setCompositionPrice(Composition c, double salesPrice) {

        c.setSalesPrice(salesPrice);

    }

    /**
     * Method for updating the values of the fields of a product object.
     * 
     * @param p                 the Product object.
     * @param name              name of the product.
     * @param description       a description of the product.
     * @param supplier          the supplier of the product. The supplier must be created in the system.
     * @param quantityInBulk    the number of products in a package, eg. 10 in one package.
     * @param purchasePrice     the price we paid the supplier for the product.
     * @param size              the size of the product measured in cubic cm.
     * @param weight            the weight of the product.
     */
    public void updateProduct(int productID, String name, String description,
                              int supplierID, int quantityInBulk, double purchasePrice,
                              double size, double weight) throws Exception {
       
        Item i = retrieveItem(productID);
        Product p = (Product)i;
        p.updateItem(name, description);
        Supplier supplier = supplierCon.getSupplier(supplierID);
        p.setSupplier(supplier);
        p.setQuantityInBulk(quantityInBulk);
        p.setPurchasePrice(purchasePrice);
        p.setSize(size);
        p.setWeight(weight);

    }

    /**
     * Method for updating the values of the fields of a composition object.
     * 
     * @param c                 the Compositon object.
     * @param name              name of the product.
     * @param description       a description of the product.
     */
    public void updateComposition(int itemID, String name, String description) throws Exception {

        Item i = retrieveItem(itemID);
        Composition c = (Composition) i;
        c.updateItem(name, description);

    }

    /**
     * Accessor method for the collection of CompositionLines in a given composition.
     * 
     * @param  c            the Composition object.
     * @return ¨compLines   a collection containing composition lines.
     */
    public ArrayList<CompositionLine> getCompositionLines(Composition c) {

        return c.getCompLines();

    }
    
    /**
     * Method for changing the quantity in a compositionLine in a composition.
     * 
     * @param cl            the CompositonLine object.
     * @param quantity      the quantity op the product.
     */
    public void changeQuantity(CompositionLine cl, int quantity) {

        cl.setQuantity(quantity);

    }
    
    /**
     * Method for deleting a compositionLine in a composition.
     * 
     * @param c     the Compositon object.
     * @param cl    the CompositionLine object to be deleted.
     */
    public void deleteCompositionLine(Composition c, CompositionLine cl) {

        c.deleteCompLine(cl);

    }

    /**
     * Method for removing an item from the container.
     * 
     * @param  itemID       the ID used to find the item.
     * @throws Exception    if item is not found.
     */
    public void deleteItem(int itemID) throws Exception {

        itemCon.deleteItem(itemID);

    }
    
    /**
     * Method for returning the itemcontainer list.
     * 
     * @return itemList     an arraylist containing items.
     */
    public ArrayList<Item> getItemList() {

        return itemCon.getItemList();

    }

}